import 'dart:async';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:detect/utils/storage_util.dart';
import 'package:log4f/log4f.dart';

class DownloadProgress {
  int status;
  int completeCode;
  String name;

  DownloadProgress(this.status, this.completeCode, this.name);
}

class OfflineMapDownloadNotifier extends ChangeNotifier {
  final MethodChannel _channel = const MethodChannel("AppChannel");
  final Completer<bool> _downloadCompleter = Completer<bool>();
  DownloadProgress? progress;

  ///0: 未下载 1:下载中 2:已下载
  int _state = 0;

  int get state => _state;

  List get _offlineMapCitys => StorageUtil.get<List>("offlineMapCitys") ?? [];

  Future<bool> get downloadend => _downloadCompleter.future;

  bool hasMap(String cityName) => cityName.isNotEmpty && _offlineMapCitys.contains(cityName);

  Future<void> download(String cityName) async {
    if (cityName.isEmpty) return;
    if (hasMap(cityName)) {
      _state = 2;
      notifyListeners();
    } else if (_state == 0) {
      _channel.invokeMethod<bool>("downloadOffline", {'cityName': cityName}).then((value) {
        if (value == true) {
          _state = 1;
          _channel.setMethodCallHandler((call) {
            if (call.method == "downloadProgress") {
              // debugPrint("地图下载 => ${call.arguments}");
              Log4f.i(msg: call.arguments.toString(), tag: "地图下载");
              progress = DownloadProgress(call.arguments['status'], call.arguments['completeCode'], call.arguments['name']);
              if (progress?.status == 4) {
                final offlineMapCitys = _offlineMapCitys;
                offlineMapCitys.remove(cityName);
                offlineMapCitys.add(cityName);
                StorageUtil.set<List>('offlineMapCitys', offlineMapCitys);
                _state = 2;
                if (!_downloadCompleter.isCompleted) _downloadCompleter.complete(true);
              } else if (progress?.status == 3) {
                _state = 0;
              }
              notifyListeners();
            }
            return Future.value(true);
          });
        }
      });
    }
  }
}
